﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cos.Core.Model.Security;
using Cos.Core.NHibernate;
using Cos.Core.Security;
using Cos.Module.Security.Data;
using NHibernate;
using NHibernate.Criterion;

namespace Cos.Module.Security.NHibernate
{
    public class SecurityRepository : RepositoryBase, ISecurityRepository
    {
        public SecurityRepository(ISessionFactory sessionFactory) : base(sessionFactory)
        {
        }
        
        public User GetUser(int userId)
        {
            return this.CurrentSession.Get<AdminUserDataModel>(userId).ToModel();
        }

        public User GetUser(string userName)
        {
            var account = this.CurrentSession.CreateCriteria<AccountDataModel>()
                 .Add(Restrictions.Eq("AccountName", userName))
                 .UniqueResult<AccountDataModel>();

            if (account == null)
            {
                Logger.ErrorFormat("No such user: {0}", userName);
                return null;
            }

            return this.CurrentSession.CreateCriteria<AdminUserDataModel>()
                    .Add(Restrictions.Eq("AccountID", account.Id))
                    .UniqueResult<AdminUserDataModel>().ToModel();
        }

        public bool ValidatePassword(User user, string passwordHash)
        {
            var userModel = this.CurrentSession.Get<AdminUserDataModel>(user.UserId);
            
            if (string.IsNullOrEmpty(passwordHash) ||
                !string.Equals(userModel.UserPwd, passwordHash))
            {
                Logger.ErrorFormat("Login password does not match : User Name : '{0}', password hash : '{1}', database password hash :'{2}'", user.UserName, passwordHash, userModel.UserPwd);
                return false;
            }

            return true;
        }

        public void UpdateUser(User user)
        {
            var userModel = this.CurrentSession.Get<AdminUserDataModel>(user.UserId);
            var cultureModel = this.CurrentSession.Get<CultureDataModel>(user.CultureCode);

            userModel.CultureCode = cultureModel.Id;
            userModel.NavId = user.RootNavId;
            userModel.UserEmail = user.Email;
            userModel.UserFirstName = user.FirstName;
            userModel.UserLastName = user.LastName;

            this.CurrentSession.SaveOrUpdate(userModel);

            // TODO Updates Role & Groups
            throw new NotImplementedException();
        }

        public void UpdatePassword(User user, string password)
        {
            var userModel = this.CurrentSession.Get<AdminUserDataModel>(user.UserId);

            userModel.UserPwd = password;

            this.CurrentSession.SaveOrUpdate(userModel);
        }
    }
}
